<template>
<div class="row">
  <div class="col-md-12">
    <my-navbar fixed="top">
      <template slot="left"> 
        <connect-server 
          @ev-connected="onConnected" 
          @ev-disconnected="onDisconnected">
        </connect-server>                            
      </template> 
      <template slot="right" v-if="connect"> 
        <select class="form-control" v-model="topoId" @change.prevent="onTopoIdChange">
          <option v-for="option in topoDevs" :value="option.topoId">{{option.devName}}</option>
        </select>
        <select class="form-control" v-model="process">
          <option v-for="option in processOptions">{{option}}</option>
        </select>
        <button class="btn btn-default" @click.prevent="onSubscribeAll">{{$t('common.subscribe')}}</button> 
      </template>      
    </my-navbar>
    <div class="col-md-12 fixed-height" v-if="connect">
      <div class="col-md-3">
        <div class="list-group">
          <a href="javascript:;" v-for="item in subList" @click.prevent="onSelect(item)" class="list-group-item" :class="{active: selected===item.key}">
            {{item.key}}
            <span class="badge" v-show="selected!==item.key">{{item.msgs.length}}</span>
            <button type="button" class="btn btn-xs pull-right btn-default" v-for="action in item.actions" v-show="selected===item.key" @click="action.doClick(item)">
              {{action.name}}
            </button>            
          </a>
        </div>
      </div>
      <div class="col-md-9">
        <table class="table table-bordered">
          <tbody>
            <tr v-for="msg in msgs" track-by="_id">
              <td style="width:20%">{{msg.date}}</td>
              <td style="max-width:600px;overflow:auto">{{msg.content}}</td>
            </tr>          
          </tbody>
        </table>
      </div>
    </div>
  </div>
</div>
</template>

<script>
import toast from 'libs/toast.js'
import store from 'share/server/vuex/store.js'
import {makeUri, newWebsocket} from 'share/server/api.js'
import ConnectServer from 'share/server/components/ConnectServer.vue'

export default {
  store,
  components: {
    'connect-server': ConnectServer
  },
  vuex: {
    getters: {
      topoSummary: (state) => state.devmng.topoSummary
    }
  },
  computed: {
    topoDevs () {
      return _.filter(this.topoSummary.list, (item) => {
        return item.devType === 'server.main'
          || item.devType === 'audioprocessor'
          || item.devType === 'peripheral'
      })
    },
    msgs () {
      let sub = _.find(this.subList, {key: this.selected})
      if (sub) {
        return sub.msgs
      } else {
        return []
      }
    }
  },
  data () {
    return {
      connect: false,
      topoId: -1,
      process: '',
      processOptions: [],
      selected: 'common',
      subList: [{
        key: 'common',
        index: 0,
        msgs: []
      }]
    }
  },
  methods: {
    onSelect (item) {
      this.selected = item.key
    },
    onTopoIdChange () {
      let processesOfDevType = {
        'server.main': ['streamsrc', 'multimedia', 'media', 'sys', 'devmng', 'ui', 'license', 'test'],
        'server.media': [],
        'audioprocessor': ['audioprocessor'],
        'encoder': [],
        'decoder': [],
        'control.stm32': [],
        'control.arm': [],
        'peripheral': ['mediaPhy', 'controlPhy'],
      }
      let topoDev = _.find(this.topoDevs, {topoId: this.topoId})
      if (topoDev) {
        let processes = _.find(processesOfDevType, function(item, key) {
          return topoDev.devType === key
        })
        if (processes) {
          this.processOptions = processes
        } else {
          this.processOptions = []
        }
        if (this.processOptions.length > 0) {
          this.process = this.processOptions[0]
        }
      }
    },
    onSubscribeAll () {
      if (!this.ws) {
        return
      }

      let subscribeUri = makeUri(this.process, this.topoId, 'cmd')
      let msg = {
        URI: subscribeUri,
        body: {
          action: 'subscribeAll'
        }
      }

      let sub = _.find(this.subList, {key: subscribeUri})
      if (sub) {
        return
      }

      this.subList.push({
        key: subscribeUri,
        index: 0,
        msgs: [],
        actions: [{
          name: '退订',
          doClick: this.onUnSubscribeAll
        }]
      }) 

      this.ws.send(JSON.stringify(msg))
      this.addMsg('common', 'subscribeAll: ' + subscribeUri)
    },
    onUnSubscribeAll (item) {
      if (!this.ws) {
        return
      }

      let subscribeUri = item.key
      let msg = {
        URI: subscribeUri,
        body: {
          action: 'unsubscribeAll'
        }
      }

      let index  = _.findIndex(this.subList, {key: subscribeUri})
      if (index < 0) {
        return
      }

      if (this.selected === subscribeUri) {
        this.selected = this.subList[0].key
      }
      this.subList.splice(index, 1)  
      
      this.ws.send(JSON.stringify(msg))
      this.addMsg('common', 'unsubscribeAll: ' + subscribeUri)    
    },
    addMsg (key, msg) {
      var item = _.find(this.subList, {key})
      if (item) {
        item.msgs.splice(0, 0, {
          date: new Date().toLocaleString(),
          content: msg,
          _id: item.index
        })
        item.index++
      }
    },
    connectWs () {
      var ws = newWebsocket('/websocket/report')
      ws.onopen = function(e) {
        toast.i(this, 'websocket', 'open success')
      }.bind(this)
      ws.onmessage = function(e) {
        let msg = JSON.parse(e.data)
        let key = msg.URI.substr(0, msg.URI.lastIndexOf('/')) + '/cmd'
        this.addMsg(key, e.data)
      }.bind(this)
      ws.onclose = function(e) {
        toast.i(this, 'websocket', 'close ' + e.data)
      }.bind(this)
      ws.onerror = function(e) {
        toast.i(this, 'websocket', 'error ' + e.data)
      }.bind(this)
      this.ws = ws      
    },
    disconnectWs () {
      if (this.ws) {
        this.ws.close()
        this.ws = null       
      }
    },
    onDisconnected () {
      this.disconnectWs()
      this.connect = false
      this.subList = [{
        key: 'common',
        index: 0,
        msgs: []        
      }]
    },
    onConnected () {
      this.connect = true
      if (this.topoDevs.length > 0) {
        this.topoId = this.topoDevs[0].topoId
        this.onTopoIdChange()
      }
      this.connectWs()
    },
  }
}
</script>

<style>
body { 
  padding-top: 70px; 
}
.fixed-height {
  max-height: 800px;
  overflow-x: hidden;
  overflow-y: auto;
}
</style>